<?php
/**
 * HttpRequest.php
 * Created by PhpStorm.
 * User: 江小波
 * Date: 2019/5/31
 * Time: 9:53
 */
namespace app\common\utils;

abstract class HttpRequest
{
    // 超时时间
    public $timeout = 5;
    // 请求头
    public $headers = [];
    // 请求参数
    public $params = [];
    // 请求URL
    protected $url = "";
    // 将curl_exec()获取的信息以文件流的形式返回，而不是直接输出。
    public $return_transfer = true;
    // 请求方式
    public $method = 'GET';
    // 设定为不验证证书和host
    public $ssl_verify_peer = false;
    public $ssl_verify_host = false;

    /**
     * 组合请求参数
     * @param array $params
     * @return mixed
     */
    abstract protected function combParams($params);
    /**
     * 组合请求头
     * @param array $params
     * @return mixed
     */
    abstract protected function combHeaders($params);

    public function __construct($url="")
    {
        if(empty($url)){
            throw new \Exception("Must set the request address!");
        }
        $this->url = $url;
    }

    /**
     * @return mixed
     * @throws \Exception
     */
    public function curl()
    {
        // curl请求(根据请求方式)
        $method = strtoupper($this->method);
        $queryParam = "";
        if($method == "GET" || $method == "DELETE"){
            $queryParam = http_build_query($this->params);
        }
        // curl初始化
        $ch = curl_init();
        if(empty($queryParam)){
            // 设置请求地址
            curl_setopt( $ch, CURLOPT_URL, $this->url ); // 设置请求地址
        }else{
            // 设置请求地址
            curl_setopt( $ch, CURLOPT_URL, $this->url."?{$queryParam}" ); // 设置请求地址
        }
        // 将curl_exec()获取的信息以文件流的形式返回，而不是直接输出。
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, $this->return_transfer );
        // 设置超时时间
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $this->timeout );
        // 设置HTTP头信息
        curl_setopt( $ch, CURLOPT_HTTPHEADER, $this->headers );
        // curl请求(根据请求方式)
        switch($method){
            case 'GET':
                curl_setopt( $ch, CURLOPT_HTTPGET, TRUE );
                break;
            case 'POST':
                curl_setopt( $ch, CURLOPT_POST, TRUE );
                curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($this->params) );
                break;
            case 'PUT':
                curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "PUT" );
                curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($this->params) );
                break;
            case 'DELETE':
                curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "DELETE" );
                curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($this->params) );
                break;
            case "OPTIONS" :
                curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "OPTIONS" );
                curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($this->params) );
                break;
        }

        // 设定为不验证证书和host
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->ssl_verify_peer );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->ssl_verify_host );

        // 获得返回值
        $document = curl_exec( $ch );

        if(curl_errno( $ch )){
            throw new \Exception("Curl request:".curl_error( $ch ), 404);
        }

        // 获取HTTP状态码
        $code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );

        if($code != 200) {
            throw new \Exception("Curl request: HTTP status is abnormal",404);
        }

        curl_close( $ch );

        return $document;

//        header('Content-Type: application/json; charset=utf-8');
//        exit($document);
    }
}
/*
$httpRequest = new \app\common\utils\HttpRequest("https://baidu.com/");
$httpRequest->method = 'GET';
$httpRequest->headers = [
    'App-Mode: api',
    'Client-Type: 0',
    'Secret: '.md5($time),
    'Type: json',
    'Time-Stamp: '.$time,
    'Encrypted: '.$encrypted,
    'Version: '.$version,
    'Debug: '.$debug
];
$httpRequest->params = [
    'name' => 'jxb',
    'age' => 26
];
$document = $httpRequest->curl();
 */